package at.fhooe.mcm12.java.parser;

import java.io.FileNotFoundException;
import java.util.Date;
import java.util.Vector;
import at.fhooe.mcm12.java.interfaces.INMEAListener;
import at.fhooe.mcm12.java.sensors.data.GPSPosition;
import at.fhooe.mcm12.java.sim.GPSSimulator;

public class NMEAParser extends Thread
{
	private static final String FILENAME = "res/nmea_logs.txt";
	private static final String FILTER = "$GPGGA";
	private static final int TIMEOUT = 500;

	private GPSSimulator m_simulator = null;
	private Vector<INMEAListener> m_listener = null;

	private boolean m_isFirstLine;

	public NMEAParser()
	{
		try
		{
			m_isFirstLine = true;
			m_listener = new Vector<INMEAListener>();
			m_simulator = new GPSSimulator(FILENAME, TIMEOUT, FILTER);
		}
		catch(FileNotFoundException fnfe)
		{
			System.err.println(fnfe.getMessage());
		}
	}

	public void addNMEAListener(INMEAListener _listener)
	{
		if(_listener != null && !m_listener.contains(_listener))
		{
			m_listener.add(_listener);
		}
	}
	
	public void run()
	{
		String line = "";
		String[] split;
		
		double lat = 0.0;
		double lon = 0.0;
		double alt = 0.0;
		
		GPSPosition position = null;
		
		while(true)
		{
			line = m_simulator.readLine();
			
			if(m_isFirstLine == false)
			{
				if(position != null)
				{
					for(INMEAListener listener : m_listener)
					{
						listener.inform(position);
					}
				}
			}
			else
			{
				m_isFirstLine = false;
			}

			if(line != "")
			{
				if(line.compareTo("#reset") == 0)
				{
					try 
					{
						m_simulator = new GPSSimulator(FILENAME, TIMEOUT, FILTER);
						continue;
					} 
					catch (FileNotFoundException f) 
					{
						System.err.println("File konnte nicht gefunden werden:\n\n" + f.getMessage());
					}
				}
				
				split = line.split(",");
				
				if(split[0].compareTo("$GPGGA")==0 && split.length == 15)
				{				
					//Latitude
					if(split[2].equals("") == false)
					{
						lat = Double.valueOf(split[2].substring(0,2)) + Double.valueOf(split[2].substring(2,9))/60.0;
						lat = (int)(lat * 100000.0) / 100000.0;
					}
					else
						lat = 0.0;

					//Longitude
					if(split[4].equals("") == false)
					{
						lon = Double.valueOf(split[4].substring(0,3)) + Double.valueOf(split[4].substring(3,10))/60.0;
						lon = (int)(lon * 100000.0) / 100000.0;
					}
					else 
						lon = 0.0;

					//Altitude
					if(split[9].equals("") == false)
					{
						alt = Double.valueOf(split[9]);
						alt = (int)(alt * 100.0) / 100.0;
					}
					else
						alt = 0.0;

					//Altitude correction
					if(split[11].equals("") == false)
					{
						alt = alt + Double.valueOf(split[11]);
						alt = (int)(alt * 100000.0) / 100000.0;
					}
					
					Date date = new Date();
					
					position = new GPSPosition(lat, lon, alt, date.getTime());
				}
			}
		}
	}
}
